package com.chuangke.lowcode.component.handle;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.chuangke.metadata.entity.SysBill;
import com.chuangke.metadata.service.SysBillService;
import com.alibaba.druid.util.StringUtils;
import com.chuangke.common.enums.OrderStatusEnum;
import com.chuangke.common.exception.ChuangkeException;
import com.chuangke.common.express.CkEvaluatorExecutor;
import com.chuangke.common.idgen.IdManager;
import com.chuangke.framework.model.BillIItemModel;
import com.chuangke.framework.model.BillItemModel;
import com.chuangke.framework.model.BillModel;
import com.chuangke.lowcode.LowCodeContext;
import com.chuangke.lowcode.component.ProgressComponent;
import com.chuangke.lowcode.util.LowCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

/**
 * 业务表单设值，单据编号，明细编号，分录编号
 */
@Component
@Transactional(rollbackFor = Throwable.class)
public class BeforeSaveBillHandleBillColumnValueComponent implements ProgressComponent {

    @Autowired
    SysBillService sysBillService;

    public void process(LowCodeContext modelContext) {
        List datas = modelContext.getDatas();
        if (datas == null || datas.isEmpty()) {
            return;
        }

        if (!(datas.get(0) instanceof BillModel)) {
            throw new ChuangkeException("数据类型错误,数据模型应继承BillModel");
        }

        SysBill sysBill = sysBillService.findById(modelContext.getFormId()) ;

        List<Field> fields = LowCodeUtils.getEntityFields(datas.get(0).getClass());

        for (Object data : datas) {
            BillModel billModel = (BillModel) data;

            fillBillId(billModel,sysBill) ;
            billModel.setStatus(OrderStatusEnum.EDIT.getCode());

            for (Field billModelFeild : fields) {
                try {
                    handleBillItemDatas(billModelFeild, billModel);
                } catch (IllegalAccessException e) {
                    throw new ChuangkeException(e);
                }
            }
        }
    }
    
    private void fillBillId(BillModel billModel,SysBill sysBill){
    	if(!StringUtils.isEmpty(billModel.getBillId())) {
    		return ;
    	}
    	
    	String billId  ;
        if(sysBill == null){
            billId = IdManager.nextId();
        }else{
            Map<String, Object> env = BeanUtil.beanToMap(billModel) ;
            billId = (String)CkEvaluatorExecutor.execute(sysBill.getCodeExpression(), env) ;
        }
        billModel.setBillId(billId);
    }

    /**
     * 为BillItemModel设值
     *
     * @param billModelFeild
     * @param billModel
     * @throws IllegalAccessException
     */
    private void handleBillItemDatas(Field billModelFeild, BillModel billModel) throws IllegalAccessException {
        billModelFeild.setAccessible(true);
        List billItemDatas = (List) billModelFeild.get(billModel);
        if (billItemDatas == null || billItemDatas.isEmpty()) {
            return;
        }

        if (!(billItemDatas.get(0) instanceof BillItemModel)) {
            throw new ChuangkeException("数据类型错误,数据模型应继承BillItemModel");
        }

        List<Field> itemFields = LowCodeUtils.getEntityFields(billItemDatas.get(0).getClass());

        int index = 0;
        for (Object billItemData : billItemDatas) {
            index++;
            BillItemModel billItemModel = (BillItemModel) billItemData;
            billItemModel.setBillId(billModel.getBillId());
            billItemModel.setBillItemId(StrUtil.fillBefore(index + "", '0', 4));

            for (Field itemField : itemFields) {
                handleBillIitemDatas(itemField, billItemModel);
            }
        }
    }

    /**
     * 为BillIItemModel设值
     *
     * @param itemField
     * @param billItemModel
     * @throws IllegalAccessException
     */
    private void handleBillIitemDatas(Field itemField, BillItemModel billItemModel) throws IllegalAccessException {
        itemField.setAccessible(true);
        List billIitemDatas = (List) itemField.get(billItemModel);
        if (billIitemDatas == null || billIitemDatas.isEmpty()) {
            return;
        }

        if (!(billIitemDatas.get(0) instanceof BillIItemModel)) {
            throw new ChuangkeException("数据类型错误,数据模型应继承BillIItemModel");
        }

        int iindex = 0;
        for (Object billIitemData : billIitemDatas) {
            iindex++;
            BillIItemModel billIitemModel = (BillIItemModel) billIitemData;
            billIitemModel.setBillId(billItemModel.getBillId());
            billIitemModel.setBillItemId(billItemModel.getBillItemId());
            billIitemModel.setBillIitemId(StrUtil.fillBefore(iindex + "", '0', 4));
        }
    }

}
